<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue实现任务管理</title>
    <link rel="stylesheet" href="../library/laydate/theme/default/laydate.css">
    <style>
        .taskTable{
            width:100%;
            overflow: hidden;
        }
        .taskTable,.taskTable td{
            border:1px solid rgb(165, 165, 165);
            border-collapse: collapse;
        }
        .taskTable td{
            width:2.5%;
            text-align: center;
        }
        .taskTable .month{
            width:22.5%;
            line-height:25px;
        }
        .taskTable tbody td{
            line-height:35px;
        }
        .tr_hover{
            background:rgb(241, 241, 241);
        }
        .taskTable tbody .tr_td_hover{
            border-width:5px;
        }
        .createTaskGroup{
            margin-top:35px;
            width:100%;
            overflow: hidden;
        }
        .createInputDate{
            margin-right:15px;
        }
        .selectInput{
            width:15px;
            height:15px;
            float:left;
            margin-left:15px;
            cursor: pointer;
        }
        .selectInputRele{
            width:100%;
            height:100%;
            position: relative;
        }
        .selectInput svg,.addTaskClose svg{
            width:100%;
            height:100%;
            cursor: pointer;
        }
        .selectInputDate{
            width:15px;
            height:15px;
            padding:0;
            border:none;
            outline: none;
            position: absolute;
            top:0;
            left:0;
            background: transparent;
            cursor: pointer;
            text-align: center;
            background:url("images/downIcon.png") 0 0 no-repeat;
            background-size: 15px 15px;
            text-indent: 9999px;
            overflow: hidden;
        }
        .noData{
            width:100%;
            height:60px;
            line-height: 60px;
            text-align: center;
            color:rgb(172, 172, 172);
        }
        .addTaskContent{
            width:100%;
            position: fixed;
            height:100%;
            top:0;
            left:0;
            background:rgba(0, 0, 0, 0.5);
            overflow: hidden;
        }
        .addTaskContentRele{
            position: relative;
            width:100%;
            height:100%;
            overflow: hidden;
        }
        .addTaskCenter{
            width:50%;
            height:auto;
            position: absolute;
            top:50%;
            left:50%;
            transform: translate(-50%,-50%);
            background:#ffffff;
            border-radius: 6px;
            text-align: center;
            overflow: hidden;
        }
        .leftText,.createInputDate,.createInputTask{
            float:left;
            padding:0;
            margin:0;
        }
        .leftText{
            text-align: right;
            width:30%;
            line-height: 35px;
        }
        .createInputDate,.createInputTask{
            box-sizing: border-box;
            width:60%;
            border:1px solid #b3b3b3;
            height:35px;
            line-height: 35px;
            background:#ffffff;
            text-indent:15px;
        }
        .defaultBtn{
            width:60%;
            height:40px;
            line-height: 40px;
            padding:0;
            border:none;
            color:#ffffff;
            background:rgb(247, 66, 11);
            cursor: pointer;
            outline: none;
            font-size:16px;
            border-radius: 4px;
        }
        .groupMarginTop{
            margin-top:35px;
        }
        .addTaskCenterRele{
            width:100%;
            height:100%;
            position: relative;
            overflow: hidden;
            padding:15px 15px 35px 15px;;
            box-sizing: border-box;
        }
        .addTaskClose{
            position: absolute;
            top:10px;
            right:10px;
            font-size:16px;
            width:18px;
            height:18px;
            cursor: pointer;
        }
        .createTaskBtn,.createTaskBtn2{
            width:auto;
            padding:0 15px;
        }
        .createTaskBtn2{
            width:180px;
            height:50px;
        }
        .outputText{
            width:100px;
            height:30px;
            float:left;
        }
        .createTaskBtn{
            float:left;
            margin-right:15px;
        }
        .buttonGray{
            background: rgb(214, 214, 214);
            color:rgb(104, 104, 104);
        }
        .tips{
            width:30%;
            height:auto;
            padding:30px 15px;
            position: fixed;
            top:50%;
            left:50%;
            transform: translate(-50%,-50%);
            background:#ffffff;
            border:1px solid rgb(194, 194, 194);
            border-radius: 6px;
            text-align: center;
            color:rgb(247, 66, 11);
            font-weight: bold;
            font-size:20px
        }
        .buttonGrayMini{
            padding:0 5px;
            height:20px;
            line-height: 20px;
            float:right;
            font-size:12px;
            margin:2px 2px 0 0;
            background:rgb(235, 235, 235);
            border:1px solid rgb(221, 221, 221);
        }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div class="taskContent" id="taskContent">
        <input type="text" id="userSelectdate" class="selectInputDate" autocomplete="off" placeholder="选择日期" title="选择日期"/>
        <table class="taskTable" v-if="taskList.length>0">
            <thead>
                <td class="month">
                    <button class="defaultBtn createTaskBtn buttonGray buttonGrayMini" @click="importDefaultTask" title="加入每个月已设置的默认任务">加入默认任务</button>
                    <template v-if="taskList[defaultIndex]">
                        {{taskList[defaultIndex].date}}
                    </template>
                </td>
                <td v-for="v in getMonthDayNumber()">{{v}}</td>
            </thead>
            <tbody>
                <template v-if="taskList[defaultIndex]">
                    <tr v-for="(v,index) in taskList[defaultIndex].task">
                        <td class="month" @click="editTaskTextShow(v, index)" title="点击可编辑">{{v.taskName}}</td>
                        <td v-for="(v2,index2) in v.taskDay" @click="updateTaskFlag(v,index,v2,index2)" title="点击切换完成状态" class="day">{{v2 | filterFlag}}</td>
                    </tr>
                </template>
            </tbody>
        </table>
        <div class="noData" v-show="taskList.length<1 || noData">暂无数据</div>
        <div class="createTaskGroup groupMarginTop">
            <button class="defaultBtn createTaskBtn" @click="addTaskFlag = true">创建任务</button>
            <!-- 导出数据 -->
            <button class="defaultBtn createTaskBtn buttonGray" @click="outputTask">{{outputDataFlag?'取消':'导出数据（点击文本框自动复制！）'}}</button>
            <button class="defaultBtn createTaskBtn buttonGray" @click="importTask">{{importDataFlag?'取消':'导入数据（粘贴到文本框后按回车！）'}}</button>
            <textarea placeholder="请粘贴到此处，按回车导入" class="outputText" v-model="importData" @keydown="importDataOk"v-show="importDataFlag"></textarea>
            <textarea class="outputText" v-model="outputData" ref="outputData" contentEditable="true" @click="clickTextareaSelectAll" v-show="outputDataFlag"></textarea>
            <button class="defaultBtn createTaskBtn buttonGray" @click="setDefaultTaskShow">设置每月默认任务</button>
        </div>

        
        <!-- 新增任务弹窗 -->
        <div class="addTaskContent" v-show="addTaskFlag">
            <div class="addTaskContentRele">
                <div class="addTaskCenter">
                    <div class="addTaskCenterRele">

                        <div class="addTaskClose" @click="addTaskClose">
                            <svg t="1608112904544" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
                                p-id="3118" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
                                <path
                                    d="M512 0C230.4 0 0 230.4 0 512s230.4 512 512 512 512-230.4 512-512S793.6 0 512 0z m0 960C265.6 960 64 758.4 64 512S265.6 64 512 64s448 201.6 448 448-201.6 448-448 448z"
                                    fill="" p-id="3119"></path>
                                <path d="M353.6 308.352l362.048 362.016-45.248 45.28L308.352 353.6z" fill="" p-id="3120"></path>
                                <path d="M670.4 308.352l45.248 45.248L353.6 715.648l-45.248-45.28z" fill="" p-id="3121"></path>
                            </svg>
                        </div>

                        <!-- 新增任务 -->
                        <div v-show="defaultTaskFlag == 'add'">
                            <div class="createTaskGroup">
                                <div class="leftText">请选择日期：</div><input type="text" id="userInputdate" class="createInputDate" autocomplete="off"/>
                            </div>
                            <div class="createTaskGroup">
                                <div class="leftText">请输入任务：</div><input type="text" class="createInputTask" v-model="inputTask"/>
                            </div>
                            <div class="createTaskGroup groupMarginTop">
                                <button class="defaultBtn createTaskBtn2" @click="createTask">创建任务</button>
                            </div>
                        </div>

                        <!-- 预设任务 -->
                        <div v-show="defaultTaskFlag == 'def'">
                            <div class="createTaskGroup">
                                <div class="leftText">请输入任务：</div><input type="text" class="createInputTask" v-model="inputDefaultTask"/>
                            </div>
                            <div class="createTaskGroup groupMarginTop">
                                <button class="defaultBtn createTaskBtn2" @click="setDefaultTask">确认添加</button>
                            </div>
                        </div>

                        <!-- 修改任务内容 -->
                        <div v-show="defaultTaskFlag == 'edit'">
                            <div class="createTaskGroup">
                                <div class="leftText">请输入任务：</div><input type="text" class="createInputTask" v-model="taskNewText"/>
                            </div>
                            <div class="createTaskGroup groupMarginTop">
                                <button class="defaultBtn createTaskBtn2" @click="editTaskText">确认修改</button>
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>

        <!-- 提示信息，2秒消失 -->
        <div class="tips" v-show="tipsFlag">{{tips}}</div>

    </div>

    <script src="../library/jquery.min.js"></script>
    <script src="../library/laydate/laydate.js"></script>
    <script src="../date/dateUtils.js"></script>
    <script>

        //用于定位，因为layui的日期选择有bug，套用在td中不显示日期面板
        $(function(){
            if(!$(".taskTable").is(":hidden")){
                $(".selectInputDate").css({
                    left:$(".month").eq(0).offset().left+7+'px',
                    top:$(".month").eq(0).offset().top+7+'px',
                });
            }
            //鼠标滑过高亮列
            $(".day").hover(function(){
                let index = $(this).index()-1;
                $(this).addClass('tr_td_hover').prevAll(".day").addClass('tr_hover');
                $(this).closest('tr').prevAll("tr").each(function(){
                    $(this).find('.day').eq(index).addClass('tr_hover');
                });
            },function(){
                let index = $(this).index()-1;
                $(this).removeClass('tr_td_hover').prevAll(".day").removeClass('tr_hover');
                $(this).closest('tr').prevAll("tr").each(function(){
                    $(this).find('.day').eq(index).removeClass('tr_hover');
                });
            });
        });

        var task = new Vue({
            el:'#taskContent',
            data:{
                taskList:[],    //全部列表数据
                defaultIndex:0, //默认显示的数据索引
                inputDate:'',   //输入的日期
                inputDateObject:{}, //输入的日期，对象形式：{year:null, month:null}
                inputTask:'',   //输入的任务
                addTaskFlag:false,  //新增弹窗是否显示
                noData:false,   //暂无数据
                outputData:null,    //导出数据内容
                outputDataFlag:false,   //导出文本框显示
                importData:null,    //导入的数据内容
                importDataFlag:false,   //导入文本框显示
                defaultTaskFlag:'add',  //预设任务弹窗状态，add为新增，def为预设任务，edit为修改
                inputDefaultTask:null,  //输入的预设任务
                tips:'这是提示信息！',  //提示信息，3秒消失
                tipsFlag:false, //提示信息状态
                taskNewText:null,   //修改任务内容，新任务内容
                taskNewTextIndex:0, //修改任务内容，该任务索引
            },
            mounted(){
                //初始化获取当前年月，用于数据初始化
                this.initYearAndMonth();
                //初始化获取本地JSON数据
                this.initGetJSON();
                //初始化获取默认数据
                this.initDefaultData();
            },
            methods:{
                //初始化获取当前年月，用于数据初始化
                initYearAndMonth(){
                    let thisDate = dateUtils.timeStamp();
                    let thisYearMonth = dateUtils.datastring(thisDate);
                    let ym_string = `${thisYearMonth.y}年${thisYearMonth.m}月`
                    return ym_string;
                },
                //初始化获取本地JSON数据
                initGetJSON(){
                    let data_local = localStorage.getItem("taskData");
                    if(data_local){
                        this.taskList = JSON.parse(data_local);
                    } 
                    //初始化日期控件
                    this.initDateController();
                },
                //初始化日期控件
                initDateController(){
                    //执行一个laydate实例
                    laydate.render({
                        elem: '#userInputdate', //指定元素
                        type: 'month',
                        format: 'yyyy年M月',
                        done:(value, date, endDate)=>{  //生成的值、日期时间对象、结束的日期时间对象
                            this.inputDate = value;
                            this.inputDateObject = date;
                        }
                    });
                    //执行一个laydate实例
                    laydate.render({
                        elem: '#userSelectdate', //指定元素
                        type: 'month',
                        format: 'yyyy年M月',
                        done:(value, date, endDate)=>{  //生成的值、日期时间对象、结束的日期时间对象
                            this.initDefaultData(value);
                        }
                    });
                },
                //初始化获取已选择年数据的索引
                initDefaultData(data){
                    let dataData = data?data:this.initYearAndMonth();
                    let flag = false;
                    for(let a=0;a<this.taskList.length;a++){
                        if(this.taskList[a].date == dataData){
                            this.defaultIndex = a;
                            flag = true;
                            this.noData = false;
                            return;
                        }
                    }
                    if(!flag){
                        this.noData = true;
                        this.tipsShow("该月没有任务！");
                    }
                },
                //返回指定月份的总天数
                getMonthDayNumber(){
                    let tk = this.taskList[this.defaultIndex];
                    let allDayNumber = laydate.getEndDate(tk.month, tk.year);
                    return allDayNumber;
                },
                //生成任务的未填项
                createTaskEmptyFlag(y,m){
                    let arr = [];
                    let allDayNumber = laydate.getEndDate(m, y);
                    for(let a=0;a<allDayNumber;a++){arr.push('');}
                    return arr;
                },
                //新建日期和任务
                createEmptyTask(){
                    this.taskList.push({
                        "date":this.inputDate,
                        "year":this.inputDateObject.year,
                        "month":this.inputDateObject.month,
                        "task":[
                            {
                                "taskName": this.inputTask,
                                "taskDay": this.createTaskEmptyFlag(this.inputDateObject.year,this.inputDateObject.month)
                            }
                        ]
                    });
                    this.clearInput();
                    localStorage.setItem("taskData", JSON.stringify(this.taskList));
                    this.addTaskFlag = false;
                    //初始化获取本月任务
                    this.initDefaultData(this.inputDate);
                    //提示信息
                    this.tipsShow('新增成功！');
                },
                //清空输入框
                clearInput(){
                    //this.inputDate  = null;
                    this.inputTask = null;
                },
                //创建任务
                createTask(){

                    //不为空
                    if(!this.inputDate || !this.inputTask){
                        //提示信息
                        this.tipsShow("请输入任务信息！");
                        return;
                    }

                    //无数据初始化
                    if(this.taskList.length == 0){
                        this.createEmptyTask();
                        return false;
                    }

                    //验证是否已存在日期
                    for(let a = 0;a < this.taskList.length;a++){
                        if(this.taskList[a] && this.taskList[a].date == this.inputDate){
                            //向日期添加新任务
                            this.taskList[a].task.push({
                                "taskName": this.inputTask,
                                "taskDay": this.createTaskEmptyFlag(this.taskList[a].year,this.taskList[a].month)
                            });
                            this.clearInput();
                            localStorage.setItem("taskData", JSON.stringify(this.taskList));
                            this.addTaskFlag = false;
                            //初始化获取本月任务
                            this.initDefaultData(this.taskList[a].date);
                            //提示信息
                            this.tipsShow('添加任务成功！');
                            return;
                        }
                    }
                    //新建日期和任务
                    this.createEmptyTask();
                },
                //修改数据
                updateTaskFlag(parentV,parentIndex,v,index){
                    let flag;
                    switch(v){
                        case '✔':
                            flag = '✘';
                            break;
                        case '✘':
                            flag = '';
                            break;
                        case '':
                            flag = '✔';
                            break;
                    }

                    this.taskList[this.defaultIndex].task[parentIndex].taskDay.splice(index,1,flag);
                    localStorage.setItem("taskData", JSON.stringify(this.taskList));
                },
                //导出数据，文本框显示
                outputTask(){
                    this.outputData = JSON.stringify(this.taskList);
                    this.outputDataFlag = !this.outputDataFlag;
                    this.importDataFlag = false;
                },
                //导入数据，文本框显示
                importTask(){
                    this.importDataFlag = !this.importDataFlag;
                    this.outputDataFlag = false;
                },
                //点击数据框全选
                clickTextareaSelectAll(){
                    this.$refs.outputData.setSelectionRange(0, 9999);
                    if (document.execCommand('copy')) {
                        document.execCommand('copy');
                        this.outputDataFlag = false;
                        this.tipsShow('复制成功，现在可以粘贴到任何地方了！');
                    }
                },
                //导入数据
                importDataOk(e){
                    if(e.key == "Enter"){
                        if(this.importData == null || !this.importData || this.importData.length < 1){this.importData=null;this.tipsShow("导入内容为空！");return;}
                        this.taskList = JSON.parse(this.importData.trim());
                        localStorage.setItem("taskData", JSON.stringify(this.taskList));
                        this.importDataFlag = false;
                    }
                },
                //关闭任务弹窗
                addTaskClose(){
                    this.addTaskFlag = false;
                    this.defaultTaskFlag = 'add';
                    this.defaultTask = [];
                },
                //预设任务弹窗
                setDefaultTaskShow(){
                    this.defaultTaskFlag = 'def';
                    this.addTaskFlag = true;
                },
                //预设任务
                setDefaultTask(){
                    if(this.inputDefaultTask == null || !this.inputDefaultTask || this.inputDefaultTask.length < 1){this.tipsShow("预设内容不能为空！");return;}
                    let defaultTaskLocal = localStorage.getItem("defaultTask");
                    if(defaultTaskLocal){
                        let obj = JSON.parse(defaultTaskLocal);
                        obj.push(this.inputDefaultTask);
                        localStorage.setItem("defaultTask", JSON.stringify(obj));
                    }else{
                        localStorage.setItem("defaultTask", JSON.stringify([this.inputDefaultTask]));
                    }
                    this.inputDefaultTask = null;
                    this.addTaskFlag = false;
                },
                //提示信息
                tipsShow(v){
                    this.tipsFlag = true;
                    this.tips = v;
                    setTimeout(()=>{
                        this.tipsFlag = false;
                    },2000);
                },
                //在指定月份导入预设
                importDefaultTask(){
                    let defaultTaskLocal = localStorage.getItem("defaultTask");
                    if(defaultTaskLocal){
                        let obj = JSON.parse(defaultTaskLocal);
                        let newarr = [];
                        let oldarr = this.taskList[this.defaultIndex].task;
                        obj.forEach((vl, index, arr) => {
                            let num = 0;
                            for(let a = 0;a < oldarr.length;a++){
                                if(oldarr[a].taskName == vl){
                                    num++;
                                }                             
                            }
                            if(num == 0){
                                this.taskList[this.defaultIndex].task.push({
                                    "taskName": vl,
                                    "taskDay": this.createTaskEmptyFlag(this.taskList[this.defaultIndex].year,this.taskList[this.defaultIndex].month)
                                });
                            }
                        });
                        localStorage.setItem("taskData", JSON.stringify(this.taskList));
                    }else{
                        this.tipsShow("没有可导入的预设任务！");
                    }
                },
                //修改任务内容弹窗
                editTaskTextShow(v, index){
                    this.defaultTaskFlag = 'edit';
                    this.addTaskFlag = true;
                    this.taskNewText = v.taskName;
                    this.taskNewTextIndex = index;
                },
                //修改任务内容
                editTaskText(){
                    this.taskList[this.defaultIndex].task[this.taskNewTextIndex].taskName = this.taskNewText;
                    this.defaultTaskFlag = 'add';
                    this.addTaskFlag = false;
                    this.taskNewText = null;
                    this.taskNewTextIndex = 0;
                    localStorage.setItem("taskData", JSON.stringify(this.taskList));
                }
            },
            filters:{
                filterFlag(v){
                    return v;
                }
            }
        });
    </script>
</body>
</html>